package com.gollum.web.service;

import cn.hutool.core.map.MapUtil;
import cn.hutool.system.*;
import com.gollum.common.utils.ip.IpUtils;
import com.gollum.web.domain.Cpu;
import com.gollum.web.domain.Jvm;
import com.gollum.web.domain.Memory;
import com.gollum.web.domain.Server;
import org.springframework.stereotype.Component;
import oshi.SystemInfo;
import oshi.hardware.CentralProcessor;
import oshi.hardware.GlobalMemory;
import oshi.hardware.HardwareAbstractionLayer;
import oshi.util.Util;

import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

/**
 * 服务监控serice
 *
 * @author Herther
 * @createTime 2022年10月20日 22:24:00
 * @since 1.0.0
 */
@Component
public class ServerMonitorService {

    /** 睡眠等待时间 1s **/
    private static final Long OSHI_WAIT = 1000L;

    private static final SystemInfo si = new SystemInfo();
    private static final HardwareAbstractionLayer hal = si.getHardware();

    /** jvm **/
    private static final String JVM ="jvm";
    /** cpu **/
    private static final String CPU ="cpu";
    /** memory **/
    private static final String MEMORY ="memory";
    /**  server **/
    private static final String SERVER ="server";

    /**
     * 获取Cpu信息
     *
     * @return Cpu信息
     * @auther: Herther
     * @since 1.0.0
     * @date: 2022/10/20 22:52
     */
    public Cpu getCpu(){
        CentralProcessor processor = hal.getProcessor();
        // CPU信息
        long[] prevTicks = processor.getSystemCpuLoadTicks();
        //睡眠等待
        Util.sleep(OSHI_WAIT);
        long[] ticks = processor.getSystemCpuLoadTicks();
        long nice = ticks[CentralProcessor.TickType.NICE.getIndex()] - prevTicks[CentralProcessor.TickType.NICE.getIndex()];
        long irq = ticks[CentralProcessor.TickType.IRQ.getIndex()] - prevTicks[CentralProcessor.TickType.IRQ.getIndex()];
        long softirq = ticks[CentralProcessor.TickType.SOFTIRQ.getIndex()] - prevTicks[CentralProcessor.TickType.SOFTIRQ.getIndex()];
        long steal = ticks[CentralProcessor.TickType.STEAL.getIndex()] - prevTicks[CentralProcessor.TickType.STEAL.getIndex()];
        long cSys = ticks[CentralProcessor.TickType.SYSTEM.getIndex()] - prevTicks[CentralProcessor.TickType.SYSTEM.getIndex()];
        long user = ticks[CentralProcessor.TickType.USER.getIndex()] - prevTicks[CentralProcessor.TickType.USER.getIndex()];
        long iowait = ticks[CentralProcessor.TickType.IOWAIT.getIndex()] - prevTicks[CentralProcessor.TickType.IOWAIT.getIndex()];
        long idle = ticks[CentralProcessor.TickType.IDLE.getIndex()] - prevTicks[CentralProcessor.TickType.IDLE.getIndex()];
        long totalCpu = user + nice + cSys + idle + iowait + irq + softirq + steal;
        Cpu cpu = new Cpu()
                .setTotal(totalCpu)
                .setCpuName(processor.getProcessorIdentifier().getName())
                .setCpuNum(processor.getPhysicalPackageCount())
                .setPhysicalNum(processor.getPhysicalProcessorCount())
                .setLogical(processor.getLogicalProcessorCount())
                .setSys(cSys)
                .setUsed(user)
                .setFree(idle);
        return cpu;
    }

    /**
     * 获取内存信息
     *
     * @auther: Herther
     * @since 1.0.0
     * @date: 2022/10/20 22:55
     */
    public Memory getMemory(){
        GlobalMemory memory = hal.getMemory();
        Memory memInfo = new Memory()
                /** 剩余 **/
                .setFree(memory.getAvailable())
                /** 已用内存 **/
                .setUsed(memory.getTotal() - memory.getAvailable())
                /** 总计 **/
                .setTotal(memory.getTotal());
        return memInfo;
    }


    /**
     * 获取服务信息
     *
     * @return 服务信息
     * @auther: Herther
     * @since 1.0.0
     * @date: 2022/10/20 22:57
     */
    public Server getServer(){
        OsInfo osInfo = SystemUtil.getOsInfo();
        HostInfo hostInfo = SystemUtil.getHostInfo();
        Server server = new Server()
                //名称
                .setServerName(hostInfo.getName())
                //ip地址
                .setServerIp(hostInfo.getAddress())
                //操作系统
                .setOsName(osInfo.getName())
                //架构
                .setOsArch(osInfo.getArch());
        return server;
    }

    /**
     * 获取JVM信息
     *
     * @return 服务信息
     * @auther: Herther
     * @since 1.0.0
     * @date: 2022/10/20 22:57
     */
    public Jvm getJvm(){
        JvmInfo jvmInfo = SystemUtil.getJvmInfo();
        Properties props = System.getProperties();
        Jvm jvm = new Jvm()
                .setVmVersion(props.getProperty("java.vm.version"))
                .setVersion(props.getProperty("java.version"))
                .setHome(props.getProperty("java.home"))
                .setTotal(Runtime.getRuntime().totalMemory())
                .setMax(Runtime.getRuntime().maxMemory())
                .setFree(Runtime.getRuntime().freeMemory());
        return jvm;
    }

    /**
     * 获取服务信息
     *
     * @return
     * @auther: Herther
     * @since 1.0.0
     * @date: 2022/10/21 21:08
     */
    public Map<String,Object> getServerInfo() {
        Map<String, Object> infor = MapUtil.newHashMap();
        infor.put(JVM, getJvm());
        infor.put(CPU, getCpu());
        infor.put(SERVER, getServer());
        infor.put(MEMORY, getMemory());
        return infor;
    }
}

